package com.heima.app.gateway.filter;

import com.heima.app.gateway.config.GatewayAuthConfig;
import com.heima.app.gateway.util.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 全局过滤器,实现GlobalFilter接口
 */
@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter {

    @Autowired
    GatewayAuthConfig gatewayAuthConfig;

    //设置不需要拦截的路径到集合中
    /*private List<String> allowUris = Arrays.asList(
      "/login/in",
            "/login/register",
            "/v2/api-docs");*/

    /**
      token认证统一过滤处理
      @param exchange
      @param chain
     @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
        //1.获取请求和响应对象(从exchange中获取)
        //(org.springframework.http.server.reactive包下的异步request和response)
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //2.判断请求路径是否需拦截
            //获取请求路径
        String path = request.getURI().getPath();
        //从配置文件中获取需放行的路径
        List<String> allowUris = gatewayAuthConfig.getAllowUrls();
            //如果拦截到的路径后缀在集合中,放行
        for(String allowUri:allowUris){
            if(path.endsWith(allowUri)){
                return chain.filter(exchange); //不需要拦截直接放行
            }
        }
        //3.获取请求头中token
        String token = request.getHeaders().getFirst("token");

        //4.判断token非空,终止
        if(StringUtils.isBlank(token)){
            //设置状态401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //终止请求
            return response.setComplete();
        }

        //5.解析token,如果失败返回401
        try {
            //获取载荷,如果解析失败,try catch捕获异常
            Claims claimsBody = AppJwtUtil.getClaimsBody(token);
            //解析结果:-1\0 有效  1\2 过期
            int i = AppJwtUtil.verifyToken(claimsBody);
            if(i<1){
                log.info("校验token成功");
                Integer userId = (Integer) claimsBody.get("id");
                //6.获取token中的userId将userId存储到请求头中
                ServerHttpRequest request1 = request.mutate().header("userId", String.valueOf(userId)).build();
                //转发到其他微服务
                ServerWebExchange exchange1 = exchange.mutate().request(request1).build();
                return chain.filter(exchange1);
            }
        }
      catch (Exception e){
            log.error("解析token失败:{}",e.getMessage());
      }
        //失败
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        return response.setComplete();
    }
}
